import re

from django.contrib.auth import logout
from courses.models import BannerCourse
from django.contrib.auth import login
from users.forms import RegisterForm, LoginForm, UserModifyEmailPwdForm
from django.core.mail import send_mail
from itsdangerous import BadData
from itsdangerous import TimedJSONWebSignatureSerializer as serializer
from users.forms import ForgetForm, ModifyPwdForm
from boxuegu import settings
from django.conf import settings
from django import http
from django.db.models import Q
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from boxuegu.settings import MEDIA_URL
from operation.models import UserCourse
from users.forms import UserInfoForm, UploadImageForm
from users.models import UserProfile
from django.http import JsonResponse
from courses.models import Course
from operation.models import UserFavorite
from organization.models import Teacher, CourseOrg
from utils.mixin_utils import LoginRequiredMixin
# 1.导入logging
import logging
from operation.models import UserMessage
from users.models import Banner
from django.core.paginator import Paginator
logger = logging.getLogger('django')


class IndexView(View):
    def get(self, request):
        banners = Banner.objects.all()
        courses = Course.objects.all().order_by('-students')[:6]
        banner_courses = BannerCourse.objects.all().order_by('-students')[:6]
        course_orgs = CourseOrg.objects.all().order_by('-students')[:15]
        context = {
            'all_banners': banners,
            'courses': courses,
            'banner_courses': banner_courses,
            'course_orgs': course_orgs,
        }

        return render(request, 'index.html', context)


class LogoutView(View):
    def get(self, request):
        """实现退出登录逻辑"""
        # 清理session
        logout(request)
        # 退出登录，重定向到登录页
        response = redirect(reverse('users:index'))


        return response


def Forget_pwd(email):
    s = serializer(secret_key=settings.SECRET_KEY, expires_in=3600)
    data = {'email': email}
    active_code = s.dumps(data)
    return settings.EMAIL_VERIFY_URL + active_code.decode()


def CheckEmail(active_code):
    s = serializer(secret_key=settings.SECRET_KEY, expires_in=3600)
    try:
        result = s.loads(active_code)
    except BadData:
        return None
    return result.get('email')


class UserRegister(View):
    def get(self, request):
        """
        获取注册页面
        :param request:
        :return:
        """
        # 生成表单对象

        register_form = RegisterForm()
        # 调用模版渲染生成表单
        return render(request, 'register.html', {'register_form': register_form})

    def post(self, request):
        """
        # 1.接受前端传递的表单数据
        # 2.验证表单数据
        # 3.判断是否验证成功(验证的email和password的格式)
        # 4.获取验证成功后的字段
        #   保存数据
        #   状态保持
        #   返回响应
        # 5.验证失败,则在注册模板中通过register_form.errors获取错误

        :param request:
        :return:
        """
        # 1、获取前端传递的表单数据
        data = request.POST
        # 2、验证表单数据
        register_form = RegisterForm(data)
        res = register_form.is_valid()  # 验证成功返回True，验证失败返回False

        if res:
            # 验证成功，则执行相应业务逻辑操作，这里就直接返回验证成功后的字段数据
            # 获取验证成功后的字段
            email = register_form.cleaned_data['email']
            password = register_form.cleaned_data['password']
            # 判断
            # 用户名
            if re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                # 保存数据
                try:
                    user = UserProfile.objects.create_user(
                        username=email,
                        email=email,
                        password=password
                    )
                except Exception as e:
                    logger.error(e)
                    return render(request, 'register.html', {'register_form': register_form,'error': '邮箱或者手机号错误'})
                # 状态保持
                login(request, user)
                return redirect(reverse("users:index"))
            elif re.match(r'^1[3-9]\d{9}$', email):
                # 保存数据
                try:
                    user = UserProfile.objects.create_user(
                        username=email,
                        mobile=email,
                        password=password
                    )
                except Exception as e:
                    logger.error(e)
                    return render(request, 'register.html', {'register_form': register_form, 'error': '邮箱或者手机号错误'})
                # 状态保持
                login(request, user)
                return redirect(reverse("users:index"))
            else:
                return render(request, 'register.html', {'register_form': register_form, 'error': '邮箱或者手机号错误'})

        # 验证失败，则在注册模板中通过register_form.errors获取错误
        return render(request, 'register.html', {'register_form': register_form})


class LoginView(View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        """
        # 接受数据(用户名，密码)
        # 验证数据(用户名，密码)
        # 判断是否验证成功
        #   状态保持
        #   返回响应
        # 验证失败,则在注册模板中通过login_form.errors获取错误

        :param request:
        :return:
        """
        # 接受数据(用户名，密码)
        data = request.POST

        # 验证数据(用户名，密码)
        login_form = LoginForm(data)
        res = login_form.is_valid()


        if res:
            username = login_form.cleaned_data['username']
            password = login_form.cleaned_data['password']

            # 验证成功，则执行相应业务逻辑操作，这里就直接返回验证成功后的字段数据
            # 获取验证成功后的字段
            from django.contrib.auth import authenticate
            user = authenticate(username=username, password=password)
            # 2.5判断user对象是否存在
            if user is None:
                return render(request, 'login.html', context={'error': '用户名或者密码错误'})

            # 状态保持
            login(request, user)
            # 返回响应
            return redirect(reverse('users:index'))
        return render(request, 'login.html', {'form_errors': login_form.errors})


# 忘记密码
class ForgetPwdView(View):
    def get(self, request):
        forget_form = ForgetForm()
        return render(request, 'forgetpwd.html', {'forget_form': forget_form})

    def post(self, request):
        data = request.POST
        forget_form = ForgetForm(data)
        forget = forget_form.is_valid()  # 验证成功返回True，验证失败返回False

        if forget:
            # 验证成功，则执行相应业务逻辑操作，这里就直接返回验证成功后的字段数据
            # 获取验证成功后的字段
            email = forget_form.cleaned_data['email']
            try:
                evf = UserProfile.objects.filter(email=email)
            except Exception as e:
                return http.HttpResponseBadRequest('数据库连接失败')
            else:
                if evf:
                    subject = '博学谷更改密码'
                    message = ''
                    from_email = '博学谷<qi_rui_hua@163.com>'
                    recipient_list = [email]
                    verify_url = Forget_pwd(email)
                    html_message = '<p>请点击此链接激活您的邮箱：</p>' \
                                   '<p><a href="%s">%s<a></p>' \
                                   '<p>如果链接不能点击，请复制地址到浏览器，然后直接打开。</p>' % (verify_url, verify_url)
                    send_mail(
                        subject=subject,
                        message=message,
                        from_email=from_email,
                        recipient_list=recipient_list,
                        html_message=html_message
                    )
                    return render(request, 'send_success.html')
                else:
                    return render(request, 'forgetpwd.html', {'forget_form': forget_form}, {'errmsg': '用户不存在'})
        else:
            return render(request, 'forgetpwd.html', {'forget_form': forget_form})


# 点击邮箱链接验证
class ResetView(View):
    def get(self, request, active_code):

        email = CheckEmail(active_code)

        if email is None:
            return http.HttpResponseBadRequest('参数错误')
        try:
            user = UserProfile.objects.filter(email=email)
        except:
            return http.HttpResponseBadRequest('参数错误')
        else:
            if user:
                return render(request, 'password_reset.html', {'email': email})
            else:
                return render(request, 'active_fail.html')


# 修改密码
class ModifypwdView(View):
    def post(self, request):
        data = request.POST
        email = data.get('email')
        modifypwdform = ModifyPwdForm(data)
        res = modifypwdform.is_valid()
        if res:
            password1 = modifypwdform.cleaned_data['password1']
            password2 = modifypwdform.cleaned_data['password2']

            if not password1 == password2:
                return render(request, 'password_reset.html', context={'errmsg': '两次密码输入的不一致'})
            try:
                user = UserProfile.objects.get(email=email)
            except:
                return render(request, 'password_reset.html', context={'errmsg': '参数错误'})
            else:
                if user:

                    user.set_password(password1)
                    user.save()
                    return render(request, 'login.html')
                else:
                    return render(request, 'password_reset.html', context={'email': email,'errmsg': '用户不存在'})
        else:
            return render(request, 'password_reset.html', {'modifypwdform': modifypwdform})


class UserCenterView(LoginRequiredMixin, View):
    '''获取用户中心'''

    def get(self, request):
        '''获取用户中心'''
        return render(request, 'usercenter-base.html')


class UserInfoView(LoginRequiredMixin, View):
    '''个人资料'''

    def get(self, request):
        '''获取个人资料'''
        return render(request, 'usercenter-info.html', {'MEDIA_URL': MEDIA_URL})

    def post(self, request):
        '''修改个人信息'''
        data = request.POST
        userinfo_form = UserInfoForm(data)
        us = userinfo_form.is_valid()
        error = userinfo_form.errors
        if us:
            user = request.user

            new_data = userinfo_form.cleaned_data
            UserProfile.objects.filter(id=user.id).update(**new_data)

            return JsonResponse({"status": "success"})
        else:
            return JsonResponse({"status": "error"})


class UploadImageView(LoginRequiredMixin, View):
    def get(self, request):
        return render(request, 'usercenter-info.html')

    def post(self, request):
        '''修改图片'''
        pic = request.FILES.get('image')
        upload_image_form = UploadImageForm(pic)
        p = upload_image_form.is_valid()
        if p:
            # 1. 创建Model对象，保存图片路径到数据库
            # user = UserProfile.objects.get(id=1) # 测试代码使用
            user = request.user
            user.image = 'image/2019/04/' + pic.name
            user.save()

            # 2. 开始处理图片，将图片写入到指定目录。
            # 拼接图片路径
            url = settings.MEDIA_ROOT + '/image/2019/04/' + pic.name
            with open(url, 'wb') as f:
                # pic.chunks()循环读取图片内容，每次只从本地磁盘读取一部分图片内容，加载到内存中，并将这一部分内容写入到目录下，写完以后，内存清空；下一次再从本地磁盘读取一部分数据放入内存。就是为了节省内存空间。
                for data in pic.chunks():
                    f.write(data)

            return JsonResponse({"status": "success", "msg": '头像修改成功'})
        else:
            return JsonResponse({"status": "error", "msg": '头像修改失败'})


class MyCourseView(LoginRequiredMixin, View):
    '''获取我的课程'''

    def get(self, request):
        '''获取我的课程'''
        user = request.user
        # user = UserProfile.objects.get(id=8) # 测试代码用

        user_courses = UserCourse.objects.filter(user=user)

        return render(request, 'usercenter-mycourse.html', {
            'user_courses': user_courses,
            'MEDIA_URL': MEDIA_URL
        })


# class MyFavOrgView(View):
class MyFavOrgView(LoginRequiredMixin, View):
    def get(self, request):
        org_list = []
        fav_list = UserFavorite.objects.filter(Q(user=request.user.id) & Q(fav_type=3))
        if fav_list:
            for item in fav_list:
                org = CourseOrg.objects.get(pk=item.fav_id)
                org_list.append(org)
        return render(request, 'usercenter-fav-org.html', {'org_list': org_list, 'MEDIA_URL': settings.MEDIA_URL})



# class MyFavTeacherView(View):
class MyFavTeacherView(LoginRequiredMixin, View):
    def get(self, request):
        teacher_list = []
        fav_list = UserFavorite.objects.filter(Q(user=request.user.id) & Q(fav_type=2))
        if fav_list:
            for item in fav_list:
                teacher = Teacher.objects.get(pk=item.fav_id)
                teacher_list.append(teacher)
        return render(request, 'usercenter-fav-teacher.html', {'teacher_list': teacher_list,
                      'MEDIA_URL': settings.MEDIA_URL})



# class MyFavCourseView(View):
class MyFavCourseView(LoginRequiredMixin, View):
    def get(self, request):
        course_list = []
        fav_list = UserFavorite.objects.filter(Q(user=request.user.id) & Q(fav_type=1))
        if fav_list:
            for item in fav_list:
                course = Course.objects.get(pk=item.fav_id)
                course_list.append(course)

        return render(request, 'usercenter-fav-course.html',
                      {'course_list': course_list, 'MEDIA_URL': settings.MEDIA_URL})


class MyMessageView(View):
    def get(self,request):
        # user = request.user.id
        messages_object_list = UserMessage.objects.filter(user=1)
        # print(messages_object_list)
        # <QuerySet [<UserMessage: UserMessage object>, <UserMessage: UserMessage object>, <UserMessage: UserMessage object>]>
        # object_list = ['messages',"你好"]
        messages_list = []

        for I in messages_object_list:
            message = I.message
            add_time = I.add_time
            has_read = I.has_read
            dict = {}
            dict["message"] = message
            dict["add_time"] = add_time
            dict["has_read"] = has_read
            messages_list.append(dict)

        # messages = UserMessage.objects.filter(user=1)
        paginator = Paginator(messages_list, 1)

        page = request.GET.get("page")
        if page == None:
            page = 1
        messages = paginator.page(page)
        print(messages)
        return render(request, 'usercenter-message.html', context = {"messages":messages, "page":page, 'MEDIA_URL': settings.MEDIA_URL})
        #     return HttpResponse({"messages":messages})


# 用户中心修改密码
class UserInfoPWD(View):
    def get(self,request):
        return render(request, 'userinfo_password_reset.html')

    def post(self,request):
        data = request.POST
        user = request.user
        usermodifypwdform = UserModifyEmailPwdForm(data)
        res = usermodifypwdform.is_valid()
        if res:
            oldpassword = usermodifypwdform.cleaned_data['oldpassword']
            password1 = usermodifypwdform.cleaned_data['password1']
            password2 = usermodifypwdform.cleaned_data['password2']

            if not password1 == password2:
                return render(request, 'password_reset.html', context={'errmsg': '两次密码输入的不一致'})
            if oldpassword == password1:
                return render(request, 'password_reset.html', context={'errmsg': '新密码与旧密码不能一致'})
            if user.check_password(oldpassword):
                user.set_password(password1)
                user.save()
                login(request, user)
                return render(request, 'usercenter-info.html')
            else:
                return render(request, 'userinfo_password_reset.html', context={'errmsg': '旧密码不正确'})
        else:
            return render(request, 'userinfo_password_reset.html', {'usermodifypwdform': usermodifypwdform})

